using System;
using Firestarter.Test.Base;
using FireStarterModeller.BO;
using Habanero.Base;
using Habanero.BO;
using NUnit.Framework;

namespace FireStarterModeller.Test.BO
{
    [TestFixture]
    public class TestDMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew
    {
       [SetUp]
        public void SetupTest()
        {
            //Runs every time that any testmethod is executed
            TestUtilsDomain.SetupTest();
            BORegistry.DataAccessor = new DataAccessorInMemory();
        }

        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            //Code that is executed before any test is run in this class. If multiple tests
            // are executed then it will still only be called once.
            TestUtilsDomain.SetupFixture();
        }

        [TearDown]
        public void TearDownTest()
        {
            //runs every time any testmethod is complete
        }

        #region TestDMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew

        [Test]
        public void Test_Contruct()
        {
            //---------------Set up test pack-------------------
            DMInheritanceRelationship dmInheritanceRelationship = new DMInheritanceRelationship();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            IBusinessObjectRule rule =
                new DMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew();
            //---------------Test Result -----------------------
            Assert.IsNotNull(rule);
        }

        [Test]
        public void Test_Construct_ShouldSupport_IBusinessObjectRule()
        {
            //---------------Set up test pack-------------------
            DMInheritanceRelationship dmInheritanceRelationship = new DMInheritanceRelationship();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            DMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew rule =
                new DMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew();
            //---------------Test Result -----------------------
            TestUtilsShared.AssertIsInstanceOf<IBusinessObjectRule>(rule);
        }

//        [Test]
//        public void Test_WhenInheritanceRelationshipNull_ShouldRaiseError()
//        {
//            //---------------Set up test pack-------------------
//            //---------------Assert Precondition----------------
//            //---------------Execute Test ----------------------
//            try
//            {
//                new DMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew(null);
//                Assert.Fail("expected ArgumentNullException");
//            }
//                //---------------Test Result -----------------------
//            catch (ArgumentNullException ex)
//            {
//                StringAssert.Contains("Value cannot be null", ex.Message);
//                StringAssert.Contains("inheritanceRelationship", ex.ParamName);
//            }
//        }

        [Test]
        public void Test_Message_ShouldSetupRuleWithRelationship()
        {
            //---------------Set up test pack-------------------
            DMInheritanceRelationship dmInheritanceRelationship = TestUtilsShared.CreateUnsavedValidDMInheritanceRelationship();
            DMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew rule = 
                new DMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            rule.IsValid(dmInheritanceRelationship);
            string message = rule.Message;
            //---------------Test Result -----------------------
            StringAssert.Contains("The Discriminator Property for the Inheritance Relationship '"+ dmInheritanceRelationship +
                                  "' is a compulsory field and the ReadWriteRule must be WriteOnce or WriteNew", message);
        }

        [Test]
        public void Test_Name_ShouldBeCorrect()
        {
            //---------------Set up test pack-------------------
            DMInheritanceRelationship dmInheritanceRelationship = TestUtilsShared.CreateUnsavedValidDMInheritanceRelationship();
            IBusinessObjectRule rule =
                new DMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            string name = rule.Name;
            //---------------Test Result -----------------------
            Assert.AreEqual("DMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew", name);
        }

        [Test]
        public void Test_Error()
        {
            //---------------Set up test pack-------------------
            DMInheritanceRelationship dmInheritanceRelationship = new DMInheritanceRelationship();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            IBusinessObjectRule rule =
                new DMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew();
            //---------------Test Result -----------------------
            Assert.AreEqual(ErrorLevel.Warning, rule.ErrorLevel);
        }

        [Test]
        public void Test_IsValid_WhenDiscriminatorNull_ShouldReturnFalse()
        {
            //---------------Set up test pack-------------------
            DMInheritanceRelationship dmInheritanceRelationship = new DMInheritanceRelationship();
            IBusinessObjectRule rule =
                new DMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew();
            //---------------Assert Precondition----------------
            Assert.IsNull(dmInheritanceRelationship.Discriminator);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmInheritanceRelationship);
            //---------------Test Result -----------------------
            Assert.IsFalse(isValid);
        }

        [Test]
        public void Test_IsValid_WhenDiscriminatorPropertyNotIsCompulsory_ShouldReturnFalse()
        {
            //---------------Set up test pack-------------------
            DMInheritanceRelationship dmInheritanceRelationship = TestUtilsShared.CreateUnsavedValidDMInheritanceRelationship();
            DMClass superClass = dmInheritanceRelationship.SuperClass;
            DMClass subClass = dmInheritanceRelationship.SubClass;
            DMProperty property = superClass.CreateDMProp();

            string discriminatorType = "Discriminator Type";
            SetPropName(property, discriminatorType);
            AddPropertyToClass(superClass, property);
            SetDiscriminator(dmInheritanceRelationship, discriminatorType);

            IBusinessObjectRule rule =
                new DMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmInheritanceRelationship.Discriminator);
            Assert.IsNotNull(subClass.GetDMProperty(discriminatorType));
            Assert.IsFalse(property.IsCompulsory);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmInheritanceRelationship);
            //---------------Test Result -----------------------
            Assert.IsFalse(isValid);
        }

        [Test]
        public void Test_IsValid_WhenDiscriminatorPropertyNotWriteOnceOrWriteNew_ShouldReturnFalse()
        {
            //---------------Set up test pack-------------------
            DMInheritanceRelationship dmInheritanceRelationship = TestUtilsShared.CreateUnsavedValidDMInheritanceRelationship();
            DMClass superClass = dmInheritanceRelationship.SuperClass;
            DMClass subClass = dmInheritanceRelationship.SubClass;
            DMProperty property = superClass.CreateDMProp();

            string discriminatorType = "Discriminator Type";
            SetPropName(property, discriminatorType);
            property.ReadWriteRule = PropReadWriteRule.ReadOnly;
            AddPropertyToClass(superClass, property);
            SetDiscriminator(dmInheritanceRelationship, discriminatorType);

            IBusinessObjectRule rule =
                new DMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmInheritanceRelationship.Discriminator);
            Assert.IsNotNull(subClass.GetDMProperty(discriminatorType));
            Assert.IsFalse(property.IsCompulsory);
            Assert.AreEqual(property.ReadWriteRule,PropReadWriteRule.ReadOnly);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmInheritanceRelationship);
            //---------------Test Result -----------------------
            Assert.IsFalse(isValid);
        }
        
        [Test]
        public void Test_IsValid_WhenDiscriminatorPropertyCompulsoryButNotWriteOnceOrWriteNew_ShouldReturnFalse()
        {
            //---------------Set up test pack-------------------
            DMInheritanceRelationship dmInheritanceRelationship = TestUtilsShared.CreateUnsavedValidDMInheritanceRelationship();
            DMClass superClass = dmInheritanceRelationship.SuperClass;
            DMClass subClass = dmInheritanceRelationship.SubClass;
            DMProperty property = superClass.CreateDMProp();

            string discriminatorType = "Discriminator Type";
            SetPropName(property, discriminatorType);
            property.Compulsory = true;
            property.ReadWriteRule = PropReadWriteRule.ReadOnly;
            AddPropertyToClass(superClass, property);
            SetDiscriminator(dmInheritanceRelationship, discriminatorType);

            IBusinessObjectRule rule =
                new DMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmInheritanceRelationship.Discriminator);
            Assert.IsNotNull(subClass.GetDMProperty(discriminatorType));
            Assert.IsTrue(property.IsCompulsory);
            Assert.AreEqual(property.ReadWriteRule,PropReadWriteRule.ReadOnly);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmInheritanceRelationship);
            //---------------Test Result -----------------------
            Assert.IsFalse(isValid);
        }
        
        [Test]
        public void Test_IsValid_WhenDiscriminatorPropertyNotCompulsoryButWriteOnce_ShouldReturnFalse()
        {
            //---------------Set up test pack-------------------
            DMInheritanceRelationship dmInheritanceRelationship = TestUtilsShared.CreateUnsavedValidDMInheritanceRelationship();
            DMClass superClass = dmInheritanceRelationship.SuperClass;
            DMClass subClass = dmInheritanceRelationship.SubClass;
            DMProperty property = superClass.CreateDMProp();

            string discriminatorType = "Discriminator Type";
            SetPropName(property, discriminatorType);
            property.ReadWriteRule = PropReadWriteRule.WriteOnce;
            AddPropertyToClass(superClass, property);
            SetDiscriminator(dmInheritanceRelationship, discriminatorType);

            IBusinessObjectRule rule =
                new DMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmInheritanceRelationship.Discriminator);
            Assert.IsNotNull(subClass.GetDMProperty(discriminatorType));
            Assert.IsFalse(property.IsCompulsory);
            Assert.AreEqual(property.ReadWriteRule,PropReadWriteRule.WriteOnce);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmInheritanceRelationship);
            //---------------Test Result -----------------------
            Assert.IsFalse(isValid);
        } 
        
        [Test]
        public void Test_IsValid_WhenDiscriminatorPropertyNotCompulsoryButWriteNew_ShouldReturnFalse()
        {
            //---------------Set up test pack-------------------
            DMInheritanceRelationship dmInheritanceRelationship = TestUtilsShared.CreateUnsavedValidDMInheritanceRelationship();
            DMClass superClass = dmInheritanceRelationship.SuperClass;
            DMClass subClass = dmInheritanceRelationship.SubClass;
            DMProperty property = superClass.CreateDMProp();

            string discriminatorType = "Discriminator Type";
            SetPropName(property, discriminatorType);
            property.ReadWriteRule = PropReadWriteRule.WriteNew;
            AddPropertyToClass(superClass, property);
            SetDiscriminator(dmInheritanceRelationship, discriminatorType);

            IBusinessObjectRule rule =
                new DMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmInheritanceRelationship.Discriminator);
            Assert.IsNotNull(subClass.GetDMProperty(discriminatorType));
            Assert.IsFalse(property.IsCompulsory);
            Assert.AreEqual(property.ReadWriteRule, PropReadWriteRule.WriteNew);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmInheritanceRelationship);
            //---------------Test Result -----------------------
            Assert.IsFalse(isValid);
        }

        [Test]
        public void Test_IsValid_WhenDiscriminatorPropertyIsCompulsoryAndIsWriteOnce_ShouldReturnTrue()
        {
            //---------------Set up test pack-------------------
            DMInheritanceRelationship dmInheritanceRelationship = TestUtilsShared.CreateUnsavedValidDMInheritanceRelationship();
            DMClass superClass = dmInheritanceRelationship.SuperClass;
            DMProperty property = superClass.CreateDMProp();

            string discriminatorType = "Discriminator Type";
            SetPropName(property, discriminatorType);
            property.Compulsory = true;
            property.ReadWriteRule = PropReadWriteRule.WriteOnce;
            AddPropertyToClass(superClass, property);
            SetDiscriminator(dmInheritanceRelationship, discriminatorType);
            
            IBusinessObjectRule rule =
                new DMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew();
            //---------------Assert Precondition----------------
            Assert.IsTrue(property.IsCompulsory);
            Assert.AreEqual(property.ReadWriteRule,PropReadWriteRule.WriteOnce);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmInheritanceRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        [Test]
        public void Test_IsValid_WhenDiscriminatorPropertyIsCompulsoryAndIsWriteNew_ShouldReturnTrue()
        {
            //---------------Set up test pack-------------------
            DMInheritanceRelationship dmInheritanceRelationship = TestUtilsShared.CreateUnsavedValidDMInheritanceRelationship();
            DMClass superClass = dmInheritanceRelationship.SuperClass;
            DMProperty property = superClass.CreateDMProp();

            string discriminatorType = "Discriminator Type";
            SetPropName(property, discriminatorType);
            property.Compulsory = true;
            property.ReadWriteRule = PropReadWriteRule.WriteNew;
            AddPropertyToClass(superClass, property);
            SetDiscriminator(dmInheritanceRelationship, discriminatorType);

            IBusinessObjectRule rule =
                new DMInheritanceRelationshipDiscriminatorMustBeCompulsoryAndWriteOnceOrWriteNew();
            //---------------Assert Precondition----------------
            Assert.IsTrue(property.IsCompulsory);
            Assert.AreEqual(property.ReadWriteRule,PropReadWriteRule.WriteNew);
            //---------------Execute Test ----------------------
            bool isValid = rule.IsValid(dmInheritanceRelationship);
            //---------------Test Result -----------------------
            Assert.IsTrue(isValid);
        }

        private void SetDiscriminator(DMInheritanceRelationship dmInheritanceRelationship, string discriminatorType)
        {
            dmInheritanceRelationship.Discriminator = discriminatorType;
        }

        private void SetPropName(DMProperty property, string discriminatorType)
        {
            property.PropertyName = discriminatorType;
        }

        private void AddPropertyToClass(DMClass superClass, DMProperty property)
        {
            superClass.Properties.Add(property);
        }

     #endregion
    }
}